package com.bupt.ilink.controller.innovationPlaza;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bupt.ilink.entity.Studyspace.CourseSource;
import com.bupt.ilink.entity.Studyspace.StudyCourseFile;
import com.bupt.ilink.entity.User;
import com.bupt.ilink.entity.innovationPlaza.*;
import com.bupt.ilink.entity.innovationPlaza.DTO.AnnouncementResponse;
import com.bupt.ilink.entity.innovationPlaza.DTO.CompetitionResponse;
import com.bupt.ilink.mapper.innovationPlaza.*;
import com.bupt.ilink.service.MinioService;
import com.bupt.ilink.service.OssService;
import com.bupt.ilink.service.innovationPlaza.CompetitionService;
import com.bupt.ilink.utils.R;
import com.bupt.ilink.utils.SnowflakeIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.core.io.InputStreamResource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.bupt.ilink.entity.innovationPlaza.InnovationPlaza.ProjectType.Competition;
import static com.bupt.ilink.entity.innovationPlaza.InnovationPlaza.ProjectType.project;

@RestController
@RequestMapping("/innovationPlaza/competition")
public class CompetitionController {

    @Autowired
    private CompetitionService competitionService;

    @Autowired
    private OssService ossService;

    @Autowired
    private CompetitionMapper competitionMapper;

    @Autowired
    private InnovationTagsMapper innovationTagsMapper;

    @Autowired
    private InnovationPlazaMapper innovationPlazaMapper;

    @Autowired
    private InnovationConnectTagsMapper innovationConnectTagsMapper;

    /**
     * @author dzy
     * @return 最常使用的8个标签(List<InnovationTags>形式)
     */
    @GetMapping("/getCommonCompetitionTags")
    public R getCommonDatasetTags(){
        try {
            return R.ok(competitionService.getCommonTags());
        } catch(Exception e){
            return R.failure("内部服务器错误：" + e);
        }
    }

    @GetMapping("/getAllCompetitions")
    public IPage<CompetitionResponse> getAllCompetitions(
            @RequestParam(required = false, defaultValue = "") String sentence,
            @RequestParam (required = false, defaultValue ="" )List<String> tags,
            @RequestParam(required = false, defaultValue = "publisher_time") String sortBy,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(required = false,defaultValue = "10") int pageSize,
            @AuthenticationPrincipal UserDetails userDetails
    ) {
        User user = (User) userDetails;
        return competitionService.getAllCompetitionsEnd(sentence,tags, sortBy, pageNum, pageSize,user.getUserId());
    }

//    @GetMapping("/searchCompetitionsByTags")
//    public IPage<CompetitionResponse> searchCompetitionsByTags(@RequestParam List<String> tags,
//                                                               @RequestParam(required = false, defaultValue = "publisher_time") String sortBy,
//                                                               @RequestParam int pageNum,
//                                                               @RequestParam(required = false, defaultValue = "10") int pageSize) {
//        return competitionService.searchCompetitionsByTags(tags, sortBy, pageNum, pageSize);
//    }

        //赛事点赞:加一个状态  已经修改为收藏
    @PostMapping("/toggleLike")
    public R toggleLike(@RequestParam Long projectId, @AuthenticationPrincipal UserDetails userDetails) {
        try {
            User user = (User) userDetails;
            String result= competitionService.toggleLike(projectId, user.getUserId());
            return R.ok(result);
        }catch (Exception e){
            return R.failure(e.getMessage());

        }

    }
    //赛事收藏

    //赛事分享
    @PostMapping("/shareProject")
    public R shareProject(@RequestParam Long projectId) {
        boolean isSuccess = competitionService.incrementShareNum(projectId);
        if(isSuccess){
            return R.ok("分享量+1");
        } else {
            return R.failure("赛事分享失败");
        }
    }

    //赛事浏览
    @PostMapping("/clickProject")
    public R clickProject(@RequestParam Long projectId) {
        boolean isSuccess = competitionService.incrementLookNum(projectId);
        if(isSuccess){
            return R.ok("点击量+1");
        } else {
            return R.failure("赛事浏览失败");
        }
    }
    //获取赛事公告详情
    @GetMapping("/getAnnouncementById")
    public R getAnnouncementInfoById(@RequestParam Long competitionId,@AuthenticationPrincipal UserDetails userDetails) {
        try {
            User user = (User) userDetails;
            return R.ok(competitionService.getAnnouncementInfoById(competitionId,user.getUserId()));
        }catch (Exception e){
            return R.failure(e.getMessage());
        }

    }
    //传入赛事公共文档
    @PostMapping("/uploadAnnouncementOSS")
    public R uploadAnnouncement(
            @RequestParam("file") MultipartFile file,
            @RequestParam("projectId") BigInteger projectId
     ) {

        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();

        // 获取文件扩展名
        String fileExtension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }else {
            return R.failure("文件解析扩展名出现错误："+originalFilename);
        }
        // 生成新文件名，使用雪花算法生成的ID
//        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
//        Long id = idGenerator.nextId();
        String newFilename = projectId+ fileExtension;
        // 获取对应的文件路径，用于关联和存储上传
        String filePath="大创广场/赛事中心/";
        //OSS上传
        if (ossService.uploadFile(file, filePath, newFilename)) {
            //更新写入数据库
            CompetitionMetadata competitionMetadata=competitionMapper.selectById(projectId);
            competitionMetadata.setTextPath(filePath+newFilename);
            competitionMapper.updateById(competitionMetadata);
            return R.ok("赛事文档导入成功，OSS文件上传成功: " + file.getOriginalFilename());
        }
        else {
            return R.failure("OSS文件上传失败: " + file.getOriginalFilename());
        }
    }
    //外部导入赛事数据
    @Transactional
    @PostMapping("/uploadCompetition")
    public R uploadCompetition(
            @RequestParam("file") MultipartFile file,
            @RequestPart("Competition") CompetitionMetadata competitionMetadata,
            @RequestParam("tags") List<String> tags,
            @RequestParam("CompetitionLink") String CompetitionLink,
            @RequestParam("CompetitionOfficialLink") String CompetitionOfficialLink
     ) {
        try {

            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();

            // 获取文件扩展名
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }else {
                return R.failure("文件解析扩展名出现错误："+originalFilename);
            }
            // 生成新文件名，使用雪花算法生成的ID
            SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(2, 2);
            Long projectId= idGenerator.nextId();
            //写入大创广场信息统计表
            InnovationPlaza innovationPlaza = new InnovationPlaza();
            innovationPlaza.setProjectId(projectId);
            innovationPlaza.setProjectType(Competition);
            innovationPlazaMapper.insert(innovationPlaza);
            //绑定ID
            competitionMetadata.setCompetitionId(projectId);
            competitionMetadata.setCompetitionLink(CompetitionLink);
            competitionMetadata.setCompetitionOfficialLink(CompetitionOfficialLink);
            //绑定对应的标签
            for (String tag : tags) {
                //判断标签是否存在
                if (innovationTagsMapper.checkTagExists("Competition", tag)==0) {
                    //标签不存在，创建标签
                    InnovationTags newtag = new InnovationTags();
                    newtag.setName(tag);
                    newtag.setTagType("Competition");
                    innovationTagsMapper.insert(newtag);
                }
                //查找标签ID
                InnovationTags newtag = innovationTagsMapper.selectOne(new QueryWrapper<InnovationTags>().eq("name", tag).eq("tag_type", "Competition"));
                //创建关联
                InnovationConnectTags connectTags = new InnovationConnectTags();
                connectTags.setProjectId(projectId);
                connectTags.setTagId(newtag.getTagId());
                innovationConnectTagsMapper.insert(connectTags);
            }
            String newFilename = projectId+ fileExtension;
            // 获取对应的文件路径，用于关联和存储上传
            String filePath="大创广场/赛事中心/";
            //OSS上传
            if (ossService.uploadFile(file, filePath, newFilename)) {
                //更新写入数据库
                competitionMetadata.setTextPath(filePath+newFilename);
                competitionMapper.insert(competitionMetadata);
                return R.ok("赛事文档导入成功，OSS文件上传成功: " + file.getOriginalFilename(),competitionMetadata);
            }
            else {
                return R.failure("OSS文件上传失败: " + file.getOriginalFilename(),competitionMetadata);
            }
        }
        catch (Exception e){
            return R.failure("赛事上传出现异常: "+e.getMessage());
        }
     }




    //获取赛事公共文档
    @GetMapping("/getAnnouncementOSS")
    public R getAnnouncementOSS(@RequestParam Long projectId) {
        CompetitionMetadata competitionMetadata=competitionMapper.selectById(projectId);
        if (competitionMetadata==null) return R.failure("赛事ID有误，该赛事不存在");
        else{
            if (competitionMetadata.getTextPath()==null) return R.failure("赛事文档不存在");
            else {
                return R.ok("成功返回赛事文档OSS链接",ossService.getFileUrl(competitionMetadata.getTextPath()));
            }
        }

    }
    //查看原文链接
    @GetMapping("/getAnnouncementLink")
    public R getAnnouncementLink(@RequestParam Long projectId) {
        CompetitionMetadata competitionMetadata=competitionMapper.selectById(projectId);
        if (competitionMetadata!=null){
            String link=competitionMetadata.getCompetitionLink();
            if (link==null) return R.failure("该赛事没有提供原文链接");
            else {
                return R.ok("成功返回原文链接",link);
            }
        }else {
            return  R.failure("赛事ID有误，该赛事不存在");
        }


    }
    //直接获取文档,转接通过后端代理来访问原链接，避免CORS 问题
    @GetMapping("/getAnnouncement")
    public ResponseEntity<Object> getAnnouncement(@RequestParam Long projectId) {
        CompetitionMetadata competitionMetadata = competitionMapper.selectById(projectId);
        if (competitionMetadata != null) {
            String link = competitionMetadata.getCompetitionLink();
            if (link == null) {
                return ResponseEntity.badRequest().body("该赛事没有提供原文链接");
            } else {
                return competitionService.getFileFromLink(link);
            }
        } else {
            return ResponseEntity.badRequest().body("赛事ID有误，该赛事不存在");
        }
    }

    @GetMapping("/getAnnouncementfile")
    public R getAnnouncementfile(@RequestParam Long projectId){
        try {
            CompetitionMetadata competitionMetadata=competitionMapper.selectById(projectId);
            if (competitionMetadata==null) return R.failure("赛事ID有误，该赛事不存在");
            else {
                Map<String, Object> responseMap;
                if (competitionMetadata.getTextPath() == null) return R.failure("赛事文档不存在");
                else {
                    // 下载文件到本地
                    File file = competitionService.downloadFileFromUrl(ossService.getFileUrl(competitionMetadata.getTextPath()));
                    // 创建InputStreamResource以返回文件
                    InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

                    // 设置HTTP响应头
                    HttpHeaders headers = new HttpHeaders();
                    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getName());
                    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
                    responseMap = new HashMap<>();
                    responseMap.put("file", file);
                    responseMap.put("resource", resource);
                    responseMap.put("headers", headers);
                }

                return R.ok(responseMap);
                }
            } catch (IOException ex) {
//            throw new RuntimeException(ex);
            return R.failure(ex.getMessage());
        }
    }

}
